package com.jsh.erp.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jsh.erp.constants.ExceptionConstants;
import com.jsh.erp.datasource.entities.BomMaterial;
import com.jsh.erp.datasource.entities.BomProcess;
import com.jsh.erp.datasource.entities.MaterialExtend;
import com.jsh.erp.datasource.mappers.BomMaterialMapper;
import com.jsh.erp.datasource.mappers.BomProcessMapper;
import com.jsh.erp.datasource.vo.BomMaterialVo;
import com.jsh.erp.exception.BusinessRunTimeException;
import com.jsh.erp.utils.BaseResponseInfo;
import com.jsh.erp.utils.ExcelUtils;
import com.jsh.erp.utils.StringUtil;
import jxl.Sheet;
import jxl.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
public class BomService {

    private Logger logger = LoggerFactory.getLogger(BomService.class);

    @Resource
    private BomMaterialMapper bomMaterialMapper;
    @Resource
    private BomProcessMapper bomProcessMapper;
    @Resource
    private MaterialExtendService  materialExtendService;


    public BaseResponseInfo getBomMaterialsByProductId(Long productId) {
        BaseResponseInfo info = new BaseResponseInfo();
        try {
            // 调用 Mapper 查询物料信息
            List<BomMaterialVo> materials = bomMaterialMapper.getBomMaterialsByProductId(productId);

            // 设置返回结果
            info.code = 200;
            info.data = materials;
        } catch (Exception e) {
            logger.error("查询物料信息失败", e);
            info.code = 500;
            info.data = "查询失败";
        }
        return info;
    }

    public BaseResponseInfo getProductionProcessesByProductId(Long productId) {
        BaseResponseInfo res = new BaseResponseInfo();
        try {
            LambdaQueryWrapper<BomProcess> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(BomProcess::getProMaterialId, productId);
            wrapper.eq(BomProcess::getDeleteFlag, "0");
            List<BomProcess> bomProcesses = bomProcessMapper.selectList(wrapper);
            res.code = 200;
            res.data = bomProcesses;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            res.code = 500;
            res.data = "查询失败";
        }
        return res;
    }

    /**
     * 导入 Excel 文件
     *
     * @param file      上传的 Excel 文件
     * @param productId
     * @return 操作结果
     */
    public BaseResponseInfo importExcel(MultipartFile file, Long productId) {
        BaseResponseInfo info = new BaseResponseInfo();
        try {
            Long beginTime = System.currentTimeMillis();
            //文件扩展名只能为xls
            String fileName = file.getOriginalFilename();
            if(StringUtil.isNotEmpty(fileName)) {
                String fileExt = fileName.substring(fileName.indexOf(".")+1);
                if(!"xls".equals(fileExt)) {
                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXTENSION_ERROR_CODE,
                            ExceptionConstants.MATERIAL_EXTENSION_ERROR_MSG);
                }
            }

            // 获取文件输入流
            InputStream inputStream = file.getInputStream();
            // 使用 jxl 解析 Excel 文件
            Workbook workbook = Workbook.getWorkbook(inputStream);
            Sheet sheet = workbook.getSheet(0);

            //获取真实的行数，剔除掉空白行
            int rows = ExcelUtils.getRightRows(sheet);

            //创建 BomMaterial 对象列表
            List<BomMaterial> bomList = new ArrayList<>();
            // 遍历每一行数据
            for (int i = 2; i < rows; i++) { // 跳过表头（前两行）
                // 解析单元格数据
                String materialCode = ExcelUtils.getContent(sheet, i, 0); //条码
                int num = Integer.parseInt(Objects.requireNonNull(ExcelUtils.getContent(sheet, i, 6))); //数量
                String remark  = ExcelUtils.getContent(sheet, i, 7); //备注

                // 构造 Bom 对象
                BomMaterial bomMaterial = new BomMaterial();
                bomMaterial.setBomBarCode(materialCode);
                bomMaterial.setNum(num);
                bomMaterial.setProMaterialId(productId);
                bomMaterial.setRemarks(remark);

                MaterialExtend infoByBarCode = materialExtendService.getInfoByBarCode(materialCode);
                bomMaterial.setAllPrice(infoByBarCode.getPurchaseDecimal().multiply(new BigDecimal(num)));

                // 添加到列表
                bomList.add(bomMaterial);
            }

            // 批量插入数据库
            if (!bomList.isEmpty()) {
                bomMaterialMapper.batchInsert(bomList);
            }

            // 关闭资源
            workbook.close();
            inputStream.close();

            Long endTime = System.currentTimeMillis();
            logger.info("导入耗时：{}", endTime-beginTime);
            info.code = 200;
            info.data = "导入成功";
        } catch (BusinessRunTimeException e) {
            info.code = e.getCode();
            info.data = e.getData().get("message");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            info.code = 500;
            info.data = "导入失败";
        }
        return info;
    }

    /**
     * 批量删除物料
     *
     * @param ids 物料ID列表
     * @return 操作结果
     */
    public BaseResponseInfo deleteBomMaterials(Long[] ids) {
        BaseResponseInfo info = new BaseResponseInfo();
        try {
            // 调用 Mapper 批量删除物料
            bomMaterialMapper.deleteBatchIds(Arrays.asList(ids));

            // 设置返回结果
            info.code = 200;
            info.data = "删除成功";
        } catch (Exception e) {
            logger.error("批量删除物料失败", e);
            info.code = 500;
            info.data = "删除失败";
        }
        return info;
    }

    public BaseResponseInfo deleteProductionProcesses(Long[] ids) {
        BaseResponseInfo info = new BaseResponseInfo();
        try {
            bomProcessMapper.deleteBatchIds(Arrays.asList(ids));
            info.code = 200;
            info.data = "删除成功";
        } catch (Exception e) {
            logger.error("批量删除生产工序失败", e);
            info.code = 500;
            info.data = "删除失败";
        }
        return info;
    }

    public BaseResponseInfo addBomMaterial(BomMaterial bomMaterial) {
        BaseResponseInfo res = new BaseResponseInfo();
        try {
            bomMaterialMapper.insert(bomMaterial);
            res.code = 200;
            res.data = "新增物料成功";
        } catch (Exception e) {
            logger.error("新增物料失败", e);
            res.code = 500;
            res.data = "新增物料失败";
        }
        return res;
    }

    public BaseResponseInfo updateBomMaterial(BomMaterial bomMaterial) {
        BaseResponseInfo res = new BaseResponseInfo();
        try {
            bomMaterialMapper.updateById(bomMaterial);
            res.code = 200;
            res.data = "更新物料成功";
        } catch (Exception e) {
            logger.error("更新物料失败", e);
            res.code = 500;
            res.data = "更新物料失败";
        }
        return res;
    }

    public void exportBomMaterials(Long productId, HttpServletResponse response) throws Exception {
        String nameStr = "条码*,名称,规格,型号,单位,多属性,数量*,备注";
        List<String> nameList = StringUtil.strToStringList(nameStr);
        String[] names = StringUtil.listToStringArray(nameList);

        List<BomMaterialVo> materials = bomMaterialMapper.getBomMaterialsByProductId(productId);
        List<Object[]> objects = new ArrayList<>();
        if(null!=materials) {
            for(BomMaterialVo bomMaterial: materials) {
                String[] objs = new String[names.length];
                objs[0] = bomMaterial.getBomBarCode();
                objs[1] = bomMaterial.getName();
                objs[2] = bomMaterial.getStandard();
                objs[3] = bomMaterial.getModel();
                objs[4] = bomMaterial.getCommodityUnit();
                objs[5] = bomMaterial.getSku();
                objs[6] = bomMaterial.getNum().toString();
                objs[7] = bomMaterial.getRemarks();
                objects.add(objs);
            }
        }

        File file = ExcelUtils.exportObjectsOneSheet("物料信息", "*导入时本行内容请勿删除，切记！", names, "物料信息", objects);
        ExcelUtils.downloadExcel(file, file.getName(), response);
    }


    public BaseResponseInfo addProductionProcess(BomProcess bomProcess) {
        BaseResponseInfo res = new BaseResponseInfo();
        try {
            bomProcessMapper.insert(bomProcess);
            res.code = 200;
            res.data = "新增生产工序成功";
        } catch (Exception e) {
            logger.error("新增生产工序失败", e);
            res.code = 500;
            res.data = "新增生产工序失败";
        }
        return res;
    }

    public BaseResponseInfo updateProductionProcess(BomProcess bomProcess) {
        BaseResponseInfo res = new BaseResponseInfo();
        try {
            bomProcessMapper.updateById(bomProcess);
            res.code = 200;
            res.data = "更新生产工序成功";
        } catch (Exception e) {
            logger.error("更新生产工序失败", e);
            res.code = 500;
            res.data = "更新生产工序失败";
        }
        return res;
    }
}
